package com.xbongbong.paas.toolbox.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author zcp
 * @version v1.0
 * @date 2019/7/2 14:04
 * @since v1.0
 */
public class CompareUtil {

    public static boolean isNeedApprove(JSONObject data, JSONObject oldData, List<String> needApproveFieldList) {
        for (int i = 0; i < needApproveFieldList.size(); i++) {
            String field = needApproveFieldList.get(i);
            Object oldValue = oldData.get(field);
            Object value = data.get(field);
            boolean isLast = i == needApproveFieldList.size() -1;
            if ((oldValue == null && value != null) || (oldValue != null && value == null)) {
                if (oldValue == null) {
                    // 空数组空对象和空字符串也算相等
                    if ((value instanceof JSONObject && ((JSONObject) value).isEmpty())
                            || (value instanceof List && ((List) value).isEmpty())
                            || (StringUtil.isEmpty(value.toString()))) {
                    } else {
                        return true;
                    }
                } else {
                    // 空数组空对象和空字符串也算相等
                    if ((oldValue instanceof JSONObject && ((JSONObject) oldValue).isEmpty())
                            || (oldValue instanceof List && ((List) oldValue).isEmpty())
                            || (StringUtil.isEmpty(oldValue.toString()))) {
                    } else {
                        return true;
                    }
                }
            } else if (oldValue == null) {
            } else {
                if (oldValue instanceof Map && (value instanceof Map)) {
                    if (compareJsonObject(JSON.parseObject(JSON.toJSONString(oldValue)) , JSON.parseObject(JSON.toJSONString(value)))) {
                        return true;
                    }
                } else if (oldValue instanceof JSONArray && (value instanceof List || value instanceof String[])) {
                    JSONArray valueArray;
                    JSONArray oldValueArray;
                    valueArray = JSONArray.parseArray(JSON.toJSONString(value));
                    oldValueArray = JSONArray.parseArray(JSON.toJSONString(oldValue));
                    if (compareJson((JSONArray) oldValueArray, valueArray)) {
                        return true;
                    } else {
                        if (isLast) {
                            return false;
                        }
                    }
                } else {
                    String json1ToStr = oldValue.toString();
                    String json2ToStr = value.toString();
                    if (RegexUtil.isNumber(json1ToStr) && RegexUtil.isNumber(json2ToStr)) {
                        if (Objects.equals(Double.valueOf(json1ToStr), Double.valueOf(json2ToStr))) {
                            if (isLast) {
                                return false;
                            }
                        } else {
                            return true;
                        }
                    } else if (!json1ToStr.equals(json2ToStr)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 比较老的值和新的值
     *
     * @param oldValue 老的值
     * @param value 新的值
     * @return
     */
    public static boolean compareObjectValue (Object oldValue, Object value) {
        if ((oldValue == null && value != null) || oldValue != null && value == null) {
            if (oldValue == null) {
                // 空数组空对象和空字符串也算相等
                if ((value instanceof JSONObject && ((JSONObject) value).isEmpty())
                        || (value instanceof List && ((List) value).isEmpty())
                        || (StringUtil.isEmpty(value.toString())) || Objects.equals(value, "[]")) {
                } else {
                    return true;
                }
            }else {
                // 空数组空对象和空字符串也算相等
                if ((oldValue instanceof JSONObject && ((JSONObject) oldValue).isEmpty())
                        || (oldValue instanceof List && ((List) oldValue).isEmpty())
                        || (StringUtil.isEmpty(oldValue.toString())) || Objects.equals(oldValue, "[]")) {
                } else {
                    return true;
                }
            }
        }else if (oldValue == null) {

        }else {
            if (oldValue instanceof Map && (value instanceof Map)) {
                if (compareJsonObject(JSON.parseObject(JSON.toJSONString(oldValue)) , JSON.parseObject(JSON.toJSONString(value)))) {
                    return true;
                }
            }else if ((oldValue instanceof JSONArray || oldValue instanceof List) &&
                    (value instanceof List || value instanceof String[] || value instanceof JSONArray)) {
                JSONArray valueArray;
                JSONArray oldValueArray;
                valueArray = JSONArray.parseArray(JSON.toJSONString(value));
                oldValueArray = JSONArray.parseArray(JSON.toJSONString(oldValue));
                if (compareJson((JSONArray) oldValueArray, valueArray)) {
                    return true;
                }
            }else {
                String json1ToStr = oldValue.toString();
                String json2ToStr = value.toString();
                if (RegexUtil.isNumber(json1ToStr) && RegexUtil.isNumber(json2ToStr)) {
                    if (Objects.equals(Double.valueOf(json1ToStr), Double.valueOf(json2ToStr))) {

                    } else {
                        return true;
                    }
                } else if (!json1ToStr.equals(json2ToStr)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 不等返回true
     * @param json1
     * @param json2
     * @return
     */
    private static boolean compareJsonObject(JSONObject json1, JSONObject json2) {
        JSONObject jsonObject1 = Objects.isNull(json1) ? new JSONObject() : json1;
        JSONObject jsonObject2 = Objects.isNull(json2) ? new JSONObject() : json2;
        if (jsonObject1.size() != jsonObject2.size()) {
            // json数量不对等，也算进审批
            return true;
        }
        for (String key : json1.keySet()) {
            if (compareJson(json1.get(key), json2.get(key))) {
                return true;
            }
        }
        return false;
    }
    /**
     * 不等返回true
     * @param json1
     * @param json2
     * @return
     */
    private static boolean compareJson(Object json1, Object json2) {
        if (json1 instanceof JSONObject && json2 instanceof JSONObject) {
            return compareJsonObject((JSONObject) json1, (JSONObject) json2);
        } else if (json1 instanceof JSONArray && json2 instanceof JSONArray) {
            return compareJson((JSONArray) json1, (JSONArray) json2);
        } else {
            if (json1 == null || json2 == null) {
                return !Objects.equals(json1,json2);
            }
            String json1ToStr = json1.toString();
            String json2ToStr = json2.toString();
            if (RegexUtil.isNumber(json1ToStr) && RegexUtil.isNumber(json2ToStr)) {
                return !Objects.equals(Double.valueOf(json1ToStr), Double.valueOf(json2ToStr));
            } else return !json1ToStr.equals(json2ToStr);
        }
    }
    /**
     * 不等返回true
     * @param json1
     * @param json2
     * @return
     */
    private static boolean compareJson(JSONArray json1, JSONArray json2) {
        if (json1 != null && json2 != null) {
            if (json1.size() != json2.size()) {
                return true;
            }
            Iterator i1 = json1.iterator();
            Iterator i2 = json2.iterator();
            while (i1.hasNext()) {
                if (i2.hasNext()) {
                    if (compareJson(i1.next(), i2.next())) {
                        return true;
                    }
                }
            }
        } else {
            if ((json1 == null && json2 == null)
                    || (json1 == null && json2.isEmpty())
                    || (json2 == null && json1.isEmpty())) {

            } else if (json1 == null) {
                return true;
            } else {
                return true;
            }
        }
        return false;
    }
    /**
     * 比较两个Object对象是否相等
     *
     * @param object1 对象1
     * @param object2 对象2
     * @return boolean true 相等，false 不相等
     * @author zcp
     * @date 2019/7/2 15:36
     * @version v1.0
     * @since v1.0
     */
    public static boolean compareObject(Object object1, Object object2) {
        Object temp = object1;
        if (object1 == null && object2 == null) {
            return true;
        } else if (object1 == null) {
            temp = object2;
        }

        if (temp instanceof JSONObject) {
            JSONObject jsonObject1 = object1 == null ? null : JsonHelperUtil.parseObject(object1.toString());
            JSONObject jsonObject2 = object2 == null ? null : JsonHelperUtil.parseObject(object2.toString());
            return compareJson(jsonObject1, jsonObject2);
        } else if (temp instanceof JSONArray) {
            JSONArray jsonArray1 = object1 == null ? null : JsonHelperUtil.parseArray(object1.toString());
            JSONArray jsonArray2 = object2 == null ? null : JsonHelperUtil.parseArray(object2.toString());
            return compareArray(jsonArray1, jsonArray2);
        } else {
            String json1ToStr = object1 == null ? "" : object1.toString();
            String json2ToStr = object2 == null ? "" : object2.toString();
            try {
                return Objects.equals(json1ToStr, json2ToStr);
            } catch (Exception e) {
                return false;
            }
        }
    }

    /**
     * 判断两个JSONArray是否相等
     * 当一个为null，另一个不为null但是size=0时，两个对象也算做相等
     *
     * @param oldArray 旧对象
     * @param newArray 新对象
     * @return boolean true 相等，false 不相等
     * @author zcp
     * @date 2019/7/2 11:29
     * @version v1.0
     * @since v1.0
     */
    public static boolean compareArray(JSONArray oldArray, JSONArray newArray) {
        boolean equal = true;
        if (oldArray == null && newArray == null) {
            //都为空，则相等
            return equal;
        } else if (oldArray == null) {
            //一个为null，另一个不为null且size大于0，则不相等
            equal = newArray.size() <= 0;
        } else if (newArray == null) {
            //一个为null，另一个不为null且size大于0，则不相等
            equal = oldArray.size() <= 0;
        } else if (!Objects.equals(oldArray.size(), newArray.size())) {
            //都不为null，则先判断size，size不同则两个对象肯定不相等
            equal = false;
        } else {
            //当大小相等，判断两个集合是否有子集关系，没有则不相等
            equal = oldArray.containsAll(newArray);
        }
        return equal;
    }

    /**
     * 比较JSONObjec
     * 注意需判断内部的key、value是否相同
     *
     * @param oldJson 旧值
     * @param newJson 新值
     * @return boolean true 相等，false 不相等
     * @author zcp
     * @date 2019/7/2 15:34
     * @version v1.0
     * @since v1.0
     */
    public static boolean compareJson(JSONObject oldJson, JSONObject newJson) {
        boolean equal = true;
        if (oldJson == null && newJson == null) {
            //都为空，则相等
            return equal;
        } else if (oldJson == null) {
            //一个为null，另一个不为null且size大于0，则不相等
            equal = newJson.size() <= 0;
        } else if (newJson == null) {
            //一个为null，另一个不为null且size大于0，则不相等
            equal = oldJson.size() <= 0;
        } else if (!Objects.equals(oldJson.size(), newJson.size())) {
            //都不为null，则先判断size，size不同则两个对象肯定不相等
            equal = false;
        } else {
            //两个JSONObject不为null，且大小相等，但是内部的key集合不相等，则对象不相等
            Set<String> oldKeys = oldJson.keySet();
            Set<String> newKeys = newJson.keySet();
            if (!Objects.equals(oldKeys, newKeys)) {
                equal = false;
            } else {
                //key集合一致，则再比较key对应的value是否相等
                Iterator<String> iterator = oldKeys.iterator();
                String key;
                while (iterator.hasNext()) {
                    key = iterator.next();
                    equal = compareObject(oldJson.get(key), newJson.get(key));
                    if (!equal) {
                        break;
                    }
                }
            }
        }
        return equal;
    }

    public static void main(String[] args) {
        String st1 = "{\"key1\":\"倚天屠龙记\",\"key2\":1,\"address\":[{\"province\":\"浙江\"},{\"city\":\"杭州\"},{\"disrtict\":\"滨江区\"}]}";
        String st2 = "{\"keyString\":\"倚天屠龙记\", \"keyInt\": 20, \"keyObj\": {\"name\": \"张三丰\"}, \"keyArr\": [{\"kongfu\": \"易筋经\", \"level\": 100}]}";

        JSONObject jsonObject1 = JSONObject.parseObject(st1);
        jsonObject1.put("1", jsonObject1);
        jsonObject1.put("2", jsonObject1);
        System.out.println(jsonObject1);
        JSONObject jsonObject2 = JSONObject.parseObject(st2);
        System.out.println(compareObject(jsonObject1, null));

        Set set = new HashSet();
        set.add(1);
        set.add("2");
        Set set2 = new HashSet();
        set2.add("2");
        set2.add(1);
        System.out.println(set + "   " + set2 + "    " + set.equals(set2));
    }
}
